layui.define(function (exports) {
	const $ = layui.$;
	/**
	 * 1.默认渲染第一个中的所有一级子元素
	 * 2.点击每个子元素自动渲染后续节点
	 * 3.修改传入数据中的指定字段名称
	 * 4.获取当前点击的是那一级元素，需要一个方法去判断返回。
	 * 5.创建节点方法,动态元素绑定事件。
	 * 6.样式标签创建
	 * 7.设置默认值
	 */
	//样式设置
	let inputType = 'checkbox';
	//当前运行是否为移动端,根据设备方向属性判断，PC设备没有方向旋转。
	let isMobile = typeof window.orientation !== 'undefined';
	//移动端单位换算
	function unitConvert(size, design_width = 375) {
		return (size / design_width) * 100 + 'vw';
	}
	function createStyle(config = {}) {
		const cascaderStyle = $('<style id="cascader-style"></style>').html(`.cascader-card-popup ul,
	.cascader-card-popup li,
	.cascader-card-popup dl,
	.cascader-card-popup dd {
		list-style: none;
		padding: 0;
		margin: 0;
	}
	.cascader-card-popup {
		--cascader-main-color:${config.color ? config.color : '#16baaa'} ;
		--cascader-border-color:${config.borderColor ? config.borderColor : '#ebebeb'} ;
		width: ${isMobile ? '100vw' : config.width ? config.width : 'fit-content'} ;
		padding: ${isMobile ? unitConvert(14) : '14px'};
		border-radius: ${isMobile ? unitConvert(6) : '14px'};
		${isMobile ? '' : 'border: 1px solid var(--cascader-border-color)'};
		position: absolute;
		background: #fff;
		box-sizing: border-box;
		${isMobile ? '' : 'box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)'};
	}
	.cascader-card-popup input[type='${inputType}'] {
		display: inline-block;
		width:${isMobile ? unitConvert(18) : '18px'} ;
		height: ${isMobile ? unitConvert(18) : '18px'};
		border-radius: ${isMobile ? unitConvert(2) : '2px'};
		cursor: pointer;
		outline: none;
		vertical-align: middle;
		border: 1px solid #b7b7b7;
		-webkit-box-sizing: border-box;
		box-sizing: border-box;
		-webkit-transition: all 0.5s;
		transition: all 0.5s;
	}

	.cascader-card-popup input[type='${inputType}']:checked {
		border: 1px solid var(--cascader-main-color);
		background: var(--cascader-main-color);
	}
	.cascader-card-popup input {
		-webkit-appearance: none;
		-moz-appearance: none;
		appearance: none;
		margin: 0;
		padding: 0;
	}
	.cascader-card-popup input[type='${inputType}']:checked::before {
		content: '';
		display: block;
		position: relative;
		width:${isMobile ? unitConvert(4) : '4px'};
		height:${isMobile ? unitConvert(7) : '7px'};
		left: 28%;
		top: 48%;
		border-right:${isMobile ? unitConvert(2) : '2px'}  solid #fff;
		border-bottom: ${isMobile ? unitConvert(2) : '2px'} solid #fff;
		-webkit-transform: rotate(45deg) translate(-50%, -50%);
		transform: rotate(45deg) translate(-50%, -50%);
		background: none;
		-webkit-transition: all 0.5s;
		transition: all 0.5s;
	}
	.cascader-card-popup .cascader-child-list {
		display: flex;
		width: fit-content;
	}
	.cascader-card-popup .cascader-top {
		display: flex;
		${isMobile ? 'box-sizing: border-box;width: 100%;overflow-x: auto;' : ''}
	}
    
	.cascader-card-popup .cascader-top .cascader-item {
		padding:${isMobile ? unitConvert(6) : '6px'}  ${isMobile ? unitConvert(16) : '20px'} ;
		border-radius:${isMobile ? unitConvert(100) : '100px'};
		font-size:${isMobile ? unitConvert(14) : '14px'} ;
		margin-right:${isMobile ? unitConvert(10) : '10px'} ;
		background-color: #efefef;
		cursor: pointer;
		    white-space: nowrap;
	}
    .cascader-top .cascader-item:last-child{
      margin-right:0;
    }
	.cascader-card-popup .cascader-top .cascader-active {
		background-color: var(--cascader-main-color);
		color: #fff;
	}
	.cascader-card-popup .cascader-select-item {
		display: flex;
		align-items: center;
		cursor: pointer;
		padding:${isMobile ? unitConvert(8) : '8px'} ;
	}
		
	.cascader-card-popup .cascader-select-item:last-child {
		margin-bottom: 0;
	}
	.cascader-card-popup .cascader-select-item.cascader-active {
		background-color: #fff;
	}
	.cascader-select-item.cascader-active .cascader-check-text {
		font-weight: 700;
	}
	.cascader-card-popup .cascader-select-item input {
		margin-right: ${isMobile ? unitConvert(5) : '5px'};
	}
	.cascader-card-popup .cascader-bg-gray {
		margin-top: ${isMobile ? unitConvert(14) : '14px'};
		width: ${isMobile ? '100%' : 'fit-content'} ;
		${isMobile ? 'overflow-x:auto' : ''};
	}
	.cascader-card-popup .cascader-link-item{
		max-height: ${config.height ? config.height : '500px'} ;
		overflow-y:auto;
		background-color: #efefef;

	}
	.cascader-card-popup .cascader-link-item::-webkit-scrollbar {
		width: 5px;
	}
	.cascader-card-popup .cascader-link-item::-webkit-scrollbar-thumb {
		background-color: #d9d9d9;
		background-clip: padding-box;
		
	}
	.cascader-card-popup .cascader-link-item .cascader-check-text {
		max-width: ${config.textWidth ? config.textWidth : '98'}px;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		font-size:${isMobile ? unitConvert(14) : '16px'};
	}
	.cascader-card-popup .cascader-link-item:nth-child(even) {
		background-color: #F5F6F8;
		
	}
	.cascader-card-popup .cascader-link-item:not(:only-child):last-child {
		background-color: #fff;
	}
	.cascader-card-popup .cascader-link-item:nth-last-child(1):nth-child(-n + 2) {
		flex:1
	}
	.cascader-card-popup .cascader-link-item:nth-last-child(1):nth-child(-n + 2) .cascader-check-text {
		max-width: inherit;
	}
	.cascader-card-popup .cascader-horn {
		position: absolute;
		top: -13px;
		left: 10%;
		border-top-width: 0;
		border-color: transparent;
		border-style: solid;
		border-bottom-color: var(--cascader-border-color);
		border-width:${isMobile ? unitConvert(6) : '6px'};;
		filter: drop-shadow(0 ${isMobile ? unitConvert(2) : '2px'}; ${isMobile ? unitConvert(12) : '12px'}; rgba(0, 0, 0, 0.03));
	}
	.cascader-card-popup .cascader-horn-bottom{
			transform: rotate(185deg);
			bottom: -13px;
			top:initial;
	}
			input[type="${inputType}"]:disabled {
				color: #cfcfcf;
				cursor: not-allowed !important;
			}
			input[type="${inputType}"]:disabled+.cascader-check-text{
				color: #cfcfcf;
				cursor: not-allowed !important;
			}	
	.cascader-card-popup .cascader-horn::after {
		content: ' ';
		top: 1px;
		margin-left: ${isMobile ? '-' + unitConvert(6) : '-6px'};;
		border-width: ${isMobile ? unitConvert(6) : '6px'};;
		position: absolute;
		display: block;
		width: 0;
		height: 0;
		border-color: transparent;
		border-style: solid;
		border-top-width: 0;
		border-bottom-color: #fff;
	}`);
		$('head').append(cascaderStyle);
	}
	/**
	 * 树形根据选中父级创建子集列表
	 * @param {Arrey} data 	- 数据
	 * @param {number} level - 级别
	 * @param {Boolean} is -是否根据select字段显示下一级数据，默认自动显示每一级第一个的下一级数据
	 */
	function childTree(data, level = 0, is = false) {
		let child = [];
		let childList = '';

		for (let k = 0; k < data.length; k++) {
			let parentItem = data[k];
			let showSelect = is ? parentItem.select : k == 0;
			// if (parentItem.select && parentItem.children && parentItem.children.length > 0) {
			if (showSelect && parentItem.children && parentItem.children.length > 0) {
				for (let i = 0; i < parentItem.children.length; i++) {
					let item = parentItem.children[i];
					childList += `
							<div class="cascader-select-item ${i == 0 ? 'cascader-active' : ''}">
								<input ${item.disabled ? 'disabled' : ''} ${item.select ? 'checked' : ''} data-parentId="${item.parent_id + ''}"  cascaderId="${item.id + ''}"  type="${inputType}" name="${item.id + ''}"/>
								<div class="cascader-check-text">${item.name}</div>
							</div>
						`;
				}
				child = `<div class="cascader-link-item">${childList}</div>`;

				child += childTree(parentItem.children, (level += 1), is);
			}
		}
		return child;
	}
	/**
	 * 根据ID获取选中得数据
	 * @param {object} data - 数据列表
	 * @param {number} id - 要查询的ID
	 */
	function getSelectItem(data, id) {
		for (let i = 0; i < data.length; i++) {
			let item = data[i];
			if (item.id == id) {
				return item;
			}
			if (item.children && item.children.length > 0) {
				let res = getSelectItem(item.children, id);
				if (res) {
					return res;
				}
			}
		}
	}
	//设置数据选中字段
	function setDataSelect(data, selectId = []) {
		let toStringData = JSON.stringify(data);
		let splitData = JSON.parse(toStringData);
		let newData = [];
		//循环遍历数据
		for (let i = 0; i < splitData.length; i++) {
			let item = splitData[i];
			selectId.forEach((childrenId) => {
				if (childrenId == item.id) {
					item.select = true;
				}
			});
			if (item.children && item.children.length > 0) {
				item.children = setDataSelect(item.children, selectId);
			}
			newData.push(item);
		}
		return newData;
	}
	//更新子节点数据并插入，用于后续调用api更新数据时刷新节点
	function updateChild(mainId, data, selectIdList) {
		let cascader = $(`#${mainId}`);
		let newData = setDataSelect(data, selectIdList);
		let child = childTree(newData);
		cascader.find('.cascader-child-list').html(child);
	}
	//创建整体结构
	function render(mainId, elem, data, selectIdList) {
		if ($(`${mainId}`).length > 0) {
			$(`${mainId}`).remove();
		}
		let list = ``;
		let newData = setDataSelect(data, selectIdList);
		//一级菜单渲染
		for (let i = 0; i < newData.length; i++) {
			let item = newData[i];
			list += `<li data-id="${item.id}" class="cascader-item ${i == 0 ? 'cascader-active' : ''} ">${item.name}</li>`;
		}
		//联级列表
		const popup = $(`<div id="${mainId}" style="display:none"  class="cascader-card-popup">
			${isMobile ? '' : '<div class="cascader-horn"></div>'} 
			<ul class="cascader-top">
				${list}
			</ul>
			<div class="cascader-bg-gray">
				<div class="cascader-child-list">
					${childTree(newData)}
				</div>
			</div>
		</div>`);
		if ($(`#${mainId}`).length > 0) {
			$(`#${mainId}`).remove();
		}
		if (!isMobile) {
			$(elem).append(popup);
		} else {
			$('body').append(popup);
		}
		return popup;
	}
	//随机ID
	function onlyId() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
			var r = (Math.random() * 16) | 0,
				v = c == 'x' ? r : (r & 0x3) | 0x8;
			return v.toString(16);
		});
	}
	//PC端打开方式
	function open(mainId, clickElement, before, after) {
		//点击其他区域关闭窗口
		$(document).on('click', function (e) {
			let cascader = $(`#${mainId}`);
			let elem = $(`${clickElement}`);
			if ($(`#${mainId}`).is(':visible') && !$(e.target).is(cascader) && !$(e.target).parents(`#${mainId}`).length && !$(e.target).is(elem)) {
				cascader.slideToggle(300);
			}
		});

		//阻止点击面板隐藏

		$(document).on('click', `#${mainId}`, (e) => {
			e.stopPropagation();
		});
		//打开弹窗

		$(document).on('click', `${clickElement}`, function (e) {
			e.stopPropagation();
			if (!$(`#${mainId}`).is(':visible')) {
				$('.cascader-card-popup').hide();
				before();
			}

			let cascader = $(`#${mainId}`);
			let elem = $(`${clickElement}`);
			let posHight = elem.outerHeight() + 6 + 'px';
			// if (e.target !== e.currentTarget) {
			// 	return;
			// }
			let distanceFromBottom = $(window).height() - elem.offset().top - elem.outerHeight();
			if (distanceFromBottom < 400) {
				cascader
					.css({
						bottom: posHight,
						top: 'initial',
					})
					.find('.cascader-horn')
					.addClass('cascader-horn-bottom');
			} else {
				cascader
					.css({
						top: posHight,
						bottom: 'initial',
					})
					.find('.cascader-horn')
					.removeClass('cascader-horn-bottom');
			}
			cascader.slideToggle(300, function () {
				after();
			});
		});
	}
	//移动端打开方式
	function mobileOpen(mainId, clickElement, before, after) {
		$(document).on('click', `${clickElement}`, function (e) {
			before();
			let h = $(`#${mainId}`).outerHeight(true);
			layer.open({
				type: 1,
				title: false,
				closeBtn: 0,
				offset: 'b',
				anim: 'slideUp', // 从下往上
				area: ['100%', h + 'px'],
				shade: 0.1,
				shadeClose: true,
				content: $(`#${mainId}`),
				success: function () {
					after();
				},
			});
		});
	}
	/**
	 * 更新选中的数据值
	 * @param {object} data - 树形数据对象
	 */
	function getSelectDataList(data, selectIdList) {
		let selectItem = [];
		selectIdList.forEach((item) => {
			let select = getSelectItem(data, item);
			selectItem.push(select);
		});
		return selectItem;
	}
	//主构造器
	function Cascader(setConfig) {
		//每一个下拉框的独有ID
		this.mainId = onlyId();
		//默认配置
		let defaultConfig = {
			elem: '', //点击打开元素
			data: [], //展示树形数据
			//当用户选中时返回用户选中的json项，用于渲染至节点上
			change: function (selectDataList, selectIdList) {}, //当用户勾选时返回选中值和ID
			value: [], //默认选中数据，存储选中元素的ID值
			style: {}, //设置样式
			before: function () {}, //点击打开之前的回调
			after: function () {}, //点击打开之后的回调
			cancel: function (selectData, selectId) {}, //取消回调，用户取消选中回调
			select: function (selectData, selectId) {}, //当前选中的值
		};
		setConfig.data = JSON.parse(JSON.stringify(setConfig.data));
		this.config = $.extend(defaultConfig, setConfig);
		//选中数据ID列表
		this.selectIdList = this.config.value ? this.config.value : [];
		//设置默认选中数据
		this.selectDataList = getSelectDataList(this.config.data, this.selectIdList);
		//如果有默认数据，触发一次改变函数
		if (this.selectIdList.length > 0) {
			this.config.change(this.selectDataList, this.selectIdList);
		}
		//设置样式
		if ($('#cascader-style').length == 0) {
			createStyle(this.config.style);
		}
		//打开元素
		if (isMobile) {
			mobileOpen(this.mainId, this.config.elem, this.config.before, this.config.after);
		} else {
			open(this.mainId, this.config.elem, this.config.before, this.config.after);
		}
		//复选框选中事件
		this.clickSelectData(this.config.change);
		//一级联动事件
		this.hoverStairMenu();
		//二级三级联动事件
		this.hoverOther();
		//初始化函数
		if (this.config.data.length > 0) {
			this.init();
		}
		//观察数据变化
		this.observe();
	}
	//初始化
	Cascader.prototype.init = function () {
		// console.log('初始化后的配置', this.config);
		//创建主体
		render(this.mainId, this.config.elem, this.config.data, this.selectIdList);
	};
	//观察树形数据变化
	Cascader.prototype.observe = function () {
		let _this = this;
		this.config = new Proxy(this.config, {
			set: function (target, prop, value, receiver) {
				// console.log('target：', target);
				// console.log('prop：', prop);
				// console.log('value：', value);
				// console.log('receiver：', receiver);
				if (prop == 'data') {
					target[prop] = value;
					_this.init();
				}
				return true;
			},
		});
	};
	//设置树形数据
	Cascader.prototype.setData = function (data) {
		if ($(`#${this.mainId}`).length > 0) {
			$(`#${this.mainId}`).remove();
		}
		this.config.data = data;
	};
	/**
	 * 鼠标移入展示二级
	 * @param {object} data - 数据列表
	 */
	Cascader.prototype.hoverStairMenu = function () {
		const _this = this;

		$(document).on('mouseenter', `#${_this.mainId} .cascader-top li`, function (e) {
			e.stopPropagation();
			let cascader = $(`#${_this.mainId}`);
			let newData = setDataSelect(_this.config.data, _this.selectIdList);
			let $this = $(this);
			let index = $this.index();
			$this.addClass('cascader-active').siblings().removeClass('cascader-active');
			cascader.find('.cascader-child-list').html(`${childTree([newData[index]])}`);
		});
	};
	/**
	 * 鼠标移入2级列表展示其他级别列表
	 * @param {object} data - 数据列表
	 */
	Cascader.prototype.hoverOther = function () {
		const _this = this;
		//移动端点击文字只做展示，无需选中
		if (isMobile) {
			$(document).on('click', `#${_this.mainId} .cascader-select-item`, function (e) {
				if (e.target.tagName != 'INPUT') {
					e.preventDefault();
				}
			});
		}

		$(document).on('mouseenter', `#${_this.mainId} .cascader-select-item`, function (e) {
			let cascader = $(`#${_this.mainId}`);
			let newData = setDataSelect(_this.config.data, _this.selectIdList);
			let $this = $(this);
			let index = $this.parent().index();
			let id = $this.find('input').attr('cascaderid');
			let cascaderLinkItem = cascader.find('.cascader-link-item');
			if (index < cascaderLinkItem.length - 1) {
				for (let i = cascaderLinkItem.length - 1; index < i; i--) {
					cascaderLinkItem.eq(i).remove();
				}
			}
			$this.addClass('cascader-active').siblings().removeClass('cascader-active');
			cascader.find('.cascader-child-list').append(`${childTree([getSelectItem(newData, id)])}`);
		});
	};
	/**
	 * 点击勾选数据
	 * @param {object} data - 数据列表
	 * @param {function} cd - 回调函数，返回勾选的ID列表和勾选数据对象。
	 */
	Cascader.prototype.clickSelectData = function (cd) {
		const _this = this;

		$(document).on('click', `#${_this.mainId} .cascader-select-item`, function (e) {
			let isSelect = $(this).find('input').prop('checked');
			if (e.target.tagName != 'INPUT' && !isMobile) {
				$(this).find('input').prop('checked', !isSelect);
			}
			if (isMobile && e.target.tagName != 'INPUT') {
				return;
			}
			let val = $(this).find('input').attr('cascaderid') + '';
			let currentData = getSelectDataList(_this.config.data, [val]);
			if ($(this).find('input').prop('checked')) {
				// 复选框被选中时的操作
				// $(this).parent().addClass('cascader-active');
				_this.selectIdList.push(val + '');
				_this.config.select(currentData[0], val);
			} else {
				_this.config.cancel(currentData[0], val);
				// 复选框取消选中时的操作
				// $(this).parent().removeClass('cascader-active');
				_this.selectIdList = _this.selectIdList.filter((el) => el !== val);
			}
			_this.selectDataList = getSelectDataList(_this.config.data, _this.selectIdList);
			cd(_this.selectDataList, _this.selectIdList);
		});
	};
	/**
	 * 删除指定ID值
	 * @param {string|number} id -id值
	 */
	Cascader.prototype.deleteSelect = function (id) {
		if (!this.config.data.length) return;
		this.selectIdList = this.selectIdList.filter((item) => item != id);
		//更新选中数据
		this.selectDataList = getSelectDataList(this.config.data, this.selectIdList);
		$(`#${this.mainId}`).find('.cascader-top li').eq(0).addClass('cascader-active').siblings().removeClass('cascader-active');
		//更新节点
		updateChild(this.mainId, this.config.data, this.selectIdList);
		//返回最新值
		this.config.change(this.selectDataList, this.selectIdList);
	};
	//获取选中的函数
	Cascader.prototype.getSelect = function () {
		this.selectDataList = getSelectDataList(this.config.data, this.selectIdList);
		return { selectIdList: this.selectIdList, selectDataList: this.selectDataList };
	};
	/**
	 * 设置选中值
	 * @param {arrey} val - 传入一个选中ID的数组对象[]
	 */
	Cascader.prototype.setSelectValue = function (val) {
		if (!this.config.data.length) return;
		this.selectIdList = val;
		//更新选中数据
		this.selectDataList = getSelectDataList(this.config.data, this.selectIdList);
		//更新节点
		updateChild(this.mainId, this.config.data, this.selectIdList);
		//返回最新值
		this.config.change(this.selectDataList, this.selectIdList);
	};
	/**
	 * 新增一条数据
	 * @param {string|number} val - 新增一条选中ID值
	 */
	Cascader.prototype.addValue = function (val) {
		if (!this.config.data.length) return;
		if (this.selectIdList.includes(val)) {
			return false;
		}
		this.selectIdList.push(val);
		//更新选中数据
		this.selectDataList = getSelectDataList(this.config.data, this.selectIdList);
		//更新节点
		updateChild(this.mainId, this.config.data, this.selectIdList);
		//返回最新值
		this.config.change(this.selectDataList, this.selectIdList);
		return val;
	};
	exports('cascader', Cascader);
});
